﻿using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using AMatysiak.Collections;

namespace AMatysiak.Comparers
{
    public class MultiColumnComparer : IComparer
    {
        private List<MultiColumnRule> rules;

        private const int EQUAL = 0;

        protected int currentCompareResult;

        private DataGridViewRow row1;
        private DataGridViewRow row2;

        protected static IComparer comparer = new AlphaNumComparer();
        public static IComparer Comparer
        {
            get { return comparer; }
        }

        public MultiColumnComparer(List<MultiColumnRule> cols)
        {
            this.rules = cols;
        }

        public int Compare(object x, object y)
        {
            initializeObjects(x, y);

            compareWithListOfColumns();

            return currentCompareResult;
        }

        private void initializeObjects(object x, object y)
        {
            row1 = (DataGridViewRow)x;
            row2 = (DataGridViewRow)y;
            currentCompareResult = EQUAL;
        }

        private void compareWithListOfColumns()
        {
            foreach (MultiColumnRule rule in rules)
            {
                if (currentResultIsNotEqual())
                    break;
                
                compareColumn(rule);
            }
        }

        private bool currentResultIsNotEqual()
        {
            return currentCompareResult != EQUAL;
        }

        private void compareColumn(MultiColumnRule rule)
        {
            string value1 = row1.Cells[rule.Key].Value.ToString();
            string value2 = row2.Cells[rule.Key].Value.ToString();

            compareValues(value1, value2);

            grantRuleDirection(rule);
        }

        protected virtual void compareValues(string value1, string value2)
        {
            currentCompareResult = comparer.Compare(value1, value2);
        }

        private void grantRuleDirection(MultiColumnRule rule)
        {
            if (currentResultIsNotEqual() && rule.Value == ListSortDirection.Descending)
                currentCompareResult *= -1;
        }
    }
}
